const Parser = require("./parser");
const Node = require("./Node");

function parse(content) {
  const stack = []; // 存储标签的栈, 父子结构的处理栈

  const parser = new Parser(content);
  const root = new Node();
  root.start = parser.index;
  root.type = "Fragment";

  const attr_value = function () {
    // todo: 可以判断一些特殊的属性 : 等等
    if (parser.next('=') && parser.next('"')) {
      const value = parser.readUntil('"');
      parser.next('"');
      return {
        value,
        type: "Attribute"
      }
    }
  }
  const attrs = function (node) {
    parser.skip();
    if (parser.current() === ">" || parser.current() === "/" && parser.current() !== ' ') { // parser.current() === "/" 是自闭合标签的 /
      return;
    }

    const attrName = parser.readUntil('=');

    node.attrs.push({
      key: attrName,
      ...attr_value()
    });

    parser.skip();

    while (parser.current() !== ">" && parser.current() !== "/") {
      attrs(node)
    }
  }

  const tag_name_close = function () {
    const tagName = parser.readUntil(">");

    const current_node = stack.pop();
    current_node.end = parser.index;

    parser.next(">")

    if (current_node.name !== tagName) {
      throw new Error(`${current_node.name},标签没有匹配到,${tagName}`);
    }
  }

  const tag_name = function () {
    const node = new Node();
    node.start = parser.index - 1;
    const tagName = parser.readUntilP(/\s+|\>/);
    node.name = tagName;
    node.type = "Element";

    // todo: attrs
    attrs(node);
    // parser.skip();
    console.log('current', parser.current())

    if (parser.next(">")) {
      stack.push(node);
      return node;
    } else if (parser.next("/>")) {
      stack.pop();
      node.selfClosing = true;
      node.end = parser.index;
    }
    return node;
  }

  const text = function () {
    const node = new Node();
    node.start = parser.index;
    const text = parser.readUntil("<");
    node.data = text;
    node.end = parser.index;
    node.type = "Text";
    return node;
  }

  const parseHTML = function () {
    let ch = parser.current();
    parser.skip();
    while (((ch = parser.current()), ch)) {
      let current_node = null;
      if (stack.length === 0) {
        current_node = root;
      } else {
        current_node = stack.slice(-1)[0];
      }

      if (parser.next("</")) {
        tag_name_close();
        parseHTML();
      } else if (parser.next("<")) {
        current_node.children.push(tag_name());
      } else {
        current_node.children.push(text());
      }
    }
    parser.skip();
    root.end = parser.index - 1;
    return root;
  }

  return parseHTML();
}
module.exports = parse;
